<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>菜单管理</title>
    <!--引入的vue.js-->
    <script src="../../js/vue.js"></script>
    <!--引入elementUI的css-->
    <link  type="text/css" rel="stylesheet" href="../../css/index.css">
    <!--引入elementUI的js-->
    <script src="../../js/index.js"></script>
    <!--引入axios.js-->
    <script src="../../js/axios.min.js"></script>
    <style>
        .menu-manage { padding: 16px; }
        .search-area { margin-bottom: 16px; padding: 16px; background-color: #f5f7fa; border-radius: 4px; }
        .table-area { margin-bottom: 16px; }
        .operation-area { margin-bottom: 16px; text-align: right; }
        .tree-dialog .el-dialog__body { max-height: 500px; overflow-y: auto; }
        .tree-node { display: flex; align-items: center; justify-content: space-between; padding: 5px 0; }
        .tree-node-content { flex: 1; }
        .tree-node-actions { margin-left: 20px; }
        .menu-type-tag { margin-left: 10px; }
        .cascader-container { margin-bottom: 20px; }
        .el-table .tree-expand-icon { cursor: pointer; margin-right: 5px; }
        .demo-table-expand { font-size: 0; }
        .demo-table-expand label { width: 90px; color: #99a9bf; }
        .demo-table-expand .el-form-item { margin-right: 0; margin-bottom: 0; width: 50%; }
        .el-table .warning-row { background: #fdf6ec; }
        .el-table .success-row { background: #f0f9eb; }
    </style>
</head>
<body>
<div id="app">
    <div class="menu-manage">
        <!-- 操作按钮区域 -->
        <div class="operation-area">
            <el-button type="primary" @click="handleAdd">新增菜单</el-button>
        </div>

        <!-- 搜索区域 -->
        <div class="search-area">
            <el-form :inline="true" :model="queryForm" class="demo-form-inline">
                <el-form-item label="菜单名称">
                    <el-input v-model="queryForm.menuName" placeholder="请输入菜单名称" clearable></el-input>
                </el-form-item>
                <el-form-item label="菜单类型">
                    <el-select v-model="queryForm.menuType" placeholder="全部" clearable>
                        <el-option label="目录" value="M"></el-option>
                        <el-option label="菜单" value="C"></el-option>
                        <el-option label="按钮" value="F"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="可见性">
                    <el-select v-model="queryForm.visible" placeholder="全部" clearable>
                        <el-option label="显示" value="0"></el-option>
                        <el-option label="隐藏" value="1"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="状态">
                    <el-select v-model="queryForm.status" placeholder="全部" clearable>
                        <el-option label="正常" value="0"></el-option>
                        <el-option label="禁用" value="1"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="onSearch">查询</el-button>
                    <el-button @click="onReset">重置</el-button>
                </el-form-item>
            </el-form>
        </div>

        <!-- 菜单表格 - 只显示一级菜单 -->
        <div class="table-area">
            <el-table
                    :data="tableData"
                    border
                    style="width: 100%"
                    row-key="menuId">
                <el-table-column prop="menuId" label="ID" width="80"></el-table-column>
                <el-table-column prop="menuName" label="菜单名称">
                    <template slot-scope="scope">
                        <span>{{ scope.row.menuName }}</span>
                        <el-tag v-if="scope.row.menuType === 'M'" size="mini" type="primary" class="menu-type-tag">目录</el-tag>
                        <el-tag v-else-if="scope.row.menuType === 'C'" size="mini" type="success" class="menu-type-tag">菜单</el-tag>
                        <el-tag v-else size="mini" type="info" class="menu-type-tag">按钮</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="url" label="路径"></el-table-column>
                <el-table-column prop="orderNum" label="排序" width="80"></el-table-column>
                <el-table-column prop="visible" label="可见性" width="80">
                    <template slot-scope="scope">
                        <el-tag :type="scope.row.visible === '0' ? 'success' : 'info'" size="mini">
                            {{ scope.row.visible === '0' ? '显示' : '隐藏' }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="status" label="状态" width="80">
                    <template slot-scope="scope">
                        <el-tag :type="scope.row.status === '0' ? 'success' : 'danger'" size="mini">
                            {{ scope.row.status === '0' ? '正常' : '禁用' }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="300">
                    <template slot-scope="scope">
                        <el-button size="mini" type="primary" @click="handleViewChildren(scope.row)">查看子菜单</el-button>
                        <el-button size="mini" type="warning" @click="handleEdit(scope.row)">编辑</el-button>
                        <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </div>

        <!-- 分页 -->
        <el-pagination
                background
                layout="total, sizes, prev, pager, next, jumper"
                :current-page="pageNo"
                :page-sizes="[10, 20, 50, 100]"
                :page-size="pageSize"
                :total="total"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange">
        </el-pagination>

        <!-- 查看子菜单对话框 -->
        <el-dialog
                :title="'子菜单管理 - ' + currentMenu.menuName"
                :visible.sync="treeDialogVisible"
                width="60%"
                class="tree-dialog">
            <div class="tree-operation" style="margin-bottom: 15px;">
                <el-button type="primary" size="mini" @click="handleAddChild">新增子菜单</el-button>
                <el-button type="info" size="mini" @click="refreshSubTree">刷新</el-button>
            </div>

            <el-tree
                    :data="subTreeData"
                    node-key="id"
                    :props="treeProps"
                    :default-expand-all="true"
                    :expand-on-click-node="false">
                <span class="tree-node" slot-scope="{ node, data }">
                    <span class="tree-node-content">
                        <span>{{ data.label }}</span>
                        <el-tag v-if="data.menuType === 'M'" size="mini" type="primary" class="menu-type-tag">目录</el-tag>
                        <el-tag v-else-if="data.menuType === 'C'" size="mini" type="success" class="menu-type-tag">菜单</el-tag>
                        <el-tag v-else size="mini" type="info" class="menu-type-tag">按钮</el-tag>
                        <span style="margin-left: 10px; color: #909399; font-size: 12px;">{{ data.url }}</span>
                    </span>
                    <span class="tree-node-actions">
                        <el-button size="mini" type="warning" @click="handleEditTreeNode(data)">编辑</el-button>
                        <el-button size="mini" type="danger" @click="handleDeleteTreeNode(data)">删除</el-button>
                    </span>
                </span>
            </el-tree>

            <div slot="footer" class="dialog-footer">
                <el-button @click="treeDialogVisible = false">关闭</el-button>
            </div>
        </el-dialog>

        <!-- 添加/编辑对话框 -->
        <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%">
            <el-form :model="menuForm" :rules="rules" ref="menuForm" label-width="100px">
                <el-form-item label="菜单名称" prop="menuName">
                    <el-input v-model="menuForm.menuName" placeholder="请输入菜单名称"></el-input>
                </el-form-item>

                <!-- 级联选择父级菜单 -->
                <el-form-item label="父级菜单" prop="parentId">
                    <el-cascader
                            v-model="menuForm.parentIdPath"
                            :options="cascaderOptions"
                            :props="cascaderProps"
                            placeholder="请选择父级菜单"
                            @change="handleCascaderChange"
                            clearable
                            style="width: 100%;">
                    </el-cascader>
                </el-form-item>

                <el-form-item label="路径" prop="url">
                    <el-input v-model="menuForm.url" placeholder="请输入路径"></el-input>
                </el-form-item>
                <el-form-item label="类型" prop="menuType">
                    <el-select v-model="menuForm.menuType" placeholder="请选择菜单类型">
                        <el-option label="目录" value="M"></el-option>
                        <el-option label="菜单" value="C"></el-option>
                        <el-option label="按钮" value="F"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="可见性" prop="visible">
                    <el-select v-model="menuForm.visible">
                        <el-option label="显示" value="0"></el-option>
                        <el-option label="隐藏" value="1"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-select v-model="menuForm.status">
                        <el-option label="正常" value="0"></el-option>
                        <el-option label="禁用" value="1"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="排序号" prop="orderNum">
                    <el-input-number v-model="menuForm.orderNum" :min="0" controls-position="right"></el-input-number>
                </el-form-item>
                <el-form-item label="权限标识" prop="perms">
                    <el-input v-model="menuForm.perms" placeholder="请输入权限标识"></el-input>
                </el-form-item>
                <el-form-item label="图标" prop="icon">
                    <el-input v-model="menuForm.icon" placeholder="请输入图标类名"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="saveMenu">确定</el-button>
            </div>
        </el-dialog>
    </div>
</div>

<script>
    // 配置axios默认路径
    axios.defaults.baseURL = '';
    // 设置请求头
    axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';

    new Vue({
        el: '#app',
        data() {
            return {
                queryForm: { menuName: '', menuType: '', visible: '', status: '' },
                tableData: [],
                allMenus: [],
                pageNo: 1,
                pageSize: 10,
                total: 0,

                // 对话框控制
                dialogVisible: false,
                treeDialogVisible: false,
                dialogTitle: '菜单信息',

                // 当前操作的菜单
                currentMenu: { menuId: 0, menuName: '' },

                // 菜单表单
                menuForm: {
                    menuId: null, menuName: '', parentId: 0, url: '', menuType: 'M',
                    visible: '0', status: '0', orderNum: 0, perms: '', icon: '',
                    parentIdPath: [] // 级联选择的路径
                },

                // 验证规则
                rules: {
                    menuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
                    menuType: [{ required: true, message: '请选择菜单类型', trigger: 'change' }],
                    orderNum: [{ required: true, message: '请输入排序号', trigger: 'blur' }]
                },

                // 子树数据
                subTreeData: [],
                treeProps: {
                    children: 'children',
                    label: 'label'
                },

                // 级联选择器相关
                cascaderOptions: [], // 级联选择器的选项
                cascaderProps: {
                    value: 'menuId',
                    label: 'menuName',
                    children: 'children',
                    checkStrictly: true, // 可以选择任意一级
                    lazy: true, // 启用懒加载
                    lazyLoad: (node, resolve) => this.loadCascaderChildren(node, resolve)
                }
            }
        },
        mounted() {
            this.getMenuList();
            this.getAllMenus();
            this.initCascaderOptions();
        },
        methods: {
            // 初始化级联选择器的顶级选项
            initCascaderOptions() {
                this.cascaderOptions = [{
                    menuId: 0,
                    menuName: '顶级菜单',
                    children: [],
                    leaf: false
                }];
            },

            // 懒加载级联选择器的子菜单
            async loadCascaderChildren(node, resolve) {
                try {
                    const level = node.level;
                    const menuId = node.value;

                    console.log('加载节点:', { level, menuId, node });

                    // 对于所有节点，都加载其子菜单
                    // 调用后端接口 根据父菜单 ID 获取子菜单列表
                    const response = await axios.get(`/vegetablemarketexpress/menu/children/${menuId}`);
                    if (response.data.code === 200) {
                        const children = response.data.data.map(item => ({
                            menuId: item.menuId,
                            menuName: item.menuName,
                            children: [], // 初始化空数组
                            leaf: !this.hasChildren(item.menuId) // 根据是否有子节点设置leaf属性
                        }));
                        console.log('加载的子菜单:', children);
                        resolve(children);
                    } else {
                        resolve([]);
                    }
                } catch (error) {
                    console.error('加载级联选择器数据失败:', error);
                    resolve([]);
                }
            },

            // 判断菜单是否有子菜单
            hasChildren(menuId) {
                return this.allMenus.some(menu => Number(menu.parentId) === Number(menuId));
            },

            // 级联选择器值变化时触发
            handleCascaderChange(value) {
                console.log('级联选择器值变化:', value);
                if (value && value.length > 0) {
                    // 最后一个值即为选中的父级菜单ID
                    this.menuForm.parentId = value[value.length - 1];
                } else {
                    this.menuForm.parentId = 0; // 顶级菜单
                }
                console.log('最终父级菜单ID:', this.menuForm.parentId);
            },

            // 获取菜单列表（只显示一级菜单）
            getMenuList() {

                // 调用后端分页查询接口，只显示一级菜单
                axios.post('/vegetablemarketexpress/menu/queryByPage', {
                    pageNo: this.pageNo,
                    pageSize: this.pageSize,
                    data: {
                        menuName: this.queryForm.menuName || null,
                        menuType: this.queryForm.menuType || null,
                        visible: this.queryForm.visible || null,
                        status: this.queryForm.status || null,
                        parentId: 0 // 只查询一级菜单
                    }
                }).then(res => {
                    if (res.data.code === 200) {
                        this.tableData = res.data.data.list;
                        this.total = res.data.data.total;
                    } else {
                        this.$message.error('获取菜单列表失败：' + res.data.msg);
                    }
                }).catch(error => {
                    this.$message.error('获取菜单列表异常：' + error.message);
                });


            },

            // 获取所有菜单（用于下拉选择）
            getAllMenus() {

                // 调用后端接口 查询所有菜单
                axios.get('/vegetablemarketexpress/menu/selectAll').then(res => {
                    if (res.data.code === 200) {
                        this.allMenus = res.data.data;
                    } else {
                        this.$message.error('获取所有菜单失败：' + res.data.msg);
                    }
                }).catch(error => {
                    this.$message.error('获取所有菜单异常：' + error.message);
                });


            },

            // 获取菜单完整名称（包含层级标识）
            getMenuFullName(menu) {
                if (menu.parentId === 0) {
                    return menu.menuName + ' (顶级)';
                }
                // 递归查找父级名称
                return menu.menuName;
            },

            // 查询
            onSearch() {
                this.pageNo = 1;
                this.getMenuList();
            },

            // 重置
            onReset() {
                this.queryForm = { menuName: '', menuType: '', visible: '', status: '' };
                this.pageNo = 1;
                this.getMenuList();
            },

            // 页大小改变
            handleSizeChange(val) {
                this.pageSize = val;
                this.pageNo = 1;
                this.getMenuList();
            },

            // 当前页改变
            handleCurrentChange(val) {
                this.pageNo = val;
                this.getMenuList();
            },

            // 查看子菜单
            handleViewChildren(row) {
                this.currentMenu = { ...row };
                this.treeDialogVisible = true;
                this.getSubTree(row.menuId);
            },

            // 获取子树
            getSubTree(parentId) {

                // 调用后端接口，获取指定菜单的子菜单树
                axios.get(`/vegetablemarketexpress/menu/subTree/${parentId}`).then(res => {
                    if (res.data.code === 200) {
                        this.subTreeData = res.data.data;
                        this.getAllMenus(); // 重新获取所有菜单
                    } else {
                        this.$message.error('获取子菜单失败：' + res.data.msg);
                    }
                }).catch(error => {
                    this.$message.error('获取子菜单异常：' + error.message);
                });

            },

            // 刷新子树
            refreshSubTree() {
                this.getSubTree(this.currentMenu.menuId);
            },

            // 新增菜单
            handleAdd() {
                this.dialogTitle = '新增菜单';
                this.menuForm = {
                    menuId: null, menuName: '', parentId: 0, url: '', menuType: '',
                    visible: '', status: '', orderNum: 0, perms: '', icon: '',
                    parentIdPath: [] // 重置级联选择器
                };
                this.dialogVisible = true;
                this.$nextTick(() => {
                    if (this.$refs.menuForm) {
                        this.$refs.menuForm.clearValidate();
                    }
                });
            },

            // 新增子菜单
            handleAddChild() {
                this.dialogTitle = '新增子菜单';
                this.menuForm = {
                    menuId: null,
                    menuName: '',
                    parentId: this.currentMenu.menuId, // 设置为当前菜单的ID
                    url: '',
                    menuType: '',
                    visible: '',
                    status: '',
                    orderNum: 0,
                    perms: '',
                    icon: '',
                    parentIdPath: [this.currentMenu.menuId] // 设置级联选择器路径
                };
                this.dialogVisible = true;
                this.treeDialogVisible = false;
                this.$nextTick(() => {
                    if (this.$refs.menuForm) {
                        this.$refs.menuForm.clearValidate();
                    }
                });
            },

            // 编辑菜单
            handleEdit(row) {
                this.dialogTitle = '编辑菜单';
                this.menuForm = JSON.parse(JSON.stringify(row));

                // 设置父级菜单路径
                this.setCascaderPath(row.parentId);

                this.dialogVisible = true;
                this.$nextTick(() => {
                    if (this.$refs.menuForm) {
                        this.$refs.menuForm.clearValidate();
                    }
                });
            },

            // 设置级联选择器的路径（编辑时使用）
            setCascaderPath(parentId) {
                if (parentId === 0) {
                    this.menuForm.parentIdPath = [0];
                    return;
                }

                // 查找父级路径
                const path = [];
                this.findParentPath(parentId, path);
                this.menuForm.parentIdPath = path;
            },

            // 递归查找父级路径
            findParentPath(menuId, path) {
                const menu = this.allMenus.find(item => Number(item.menuId) === Number(menuId));
                if (menu) {
                    if (Number(menu.parentId) !== 0) {
                        this.findParentPath(menu.parentId, path);
                    }
                    path.push(Number(menu.menuId));
                }
            },

            // 编辑树节点
            handleEditTreeNode(node) {
                // 将TreeNode转换为Menu格式
                const menuData = {
                    menuId: node.id,
                    menuName: node.label,
                    parentId: node.parentId,
                    url: node.url,
                    menuType: node.menuType,
                    visible: node.visible,
                    status: node.status,
                    orderNum: node.orderNum,
                    perms: node.perms,
                    icon: node.icon
                };

                this.dialogTitle = '编辑菜单';
                this.menuForm = menuData;

                // 设置父级菜单路径
                this.setCascaderPath(node.parentId);

                this.dialogVisible = true;
                this.treeDialogVisible = false;
            },

            // 删除菜单
            handleDelete(row) {
                this.deleteMenu(row, '此操作将永久删除该菜单及其所有子菜单，是否继续?');
            },

            // 删除树节点
            handleDeleteTreeNode(node) {
                const menuData = {
                    menuId: node.id,
                    menuName: node.label
                };
                this.deleteMenu(menuData, `此操作将永久删除菜单"${node.label}"及其所有子菜单，是否继续?`);
            },

            // 通用删除方法
            deleteMenu(menu, message) {
                this.$confirm(message, '警告', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    // 调用后端接口，删除 菜单
                    axios.delete(`/vegetablemarketexpress/menu/delete/${menu.menuId}`).then(res => {
                        if (res.data.code === 200) {
                            this.$message({ type: 'success', message: '删除成功!' });
                            this.getMenuList();
                            this.getAllMenus();
                            if (this.treeDialogVisible) {
                                this.refreshSubTree();
                            }
                        } else {
                            this.$message.error('删除失败：' + res.data.msg);
                        }
                    }).catch(error => {
                        this.$message.error('删除异常：' + error.message);
                    });
                 }).catch(() => {
                    this.$message({ type: 'info', message: '已取消删除' });
                });
            },

            // 保存菜单
            saveMenu() {
                this.$refs.menuForm.validate(valid => {
                    if (valid) {
                        // 确保parentId正确设置
                        if (this.menuForm.parentIdPath && this.menuForm.parentIdPath.length > 0) {
                            this.menuForm.parentId = this.menuForm.parentIdPath[this.menuForm.parentIdPath.length - 1];
                        } else {
                            this.menuForm.parentId = 0;
                        }

                        // 检查是否选择了自己作为父级
                        if (this.menuForm.menuId && this.menuForm.parentId === this.menuForm.menuId) {
                            this.$message.error('不能选择自己作为父级菜单');
                            return;
                        }
                        let request;
                        if (this.menuForm.menuId) {
                            // 更新菜单
                            request = axios.put('/vegetablemarketexpress/menu/update', this.menuForm);
                        } else {
                            // 新增菜单
                            request = axios.post('/vegetablemarketexpress/menu/insert', this.menuForm);
                        }

                        request.then(res => {
                            if (res.data.code === 200) {
                                this.$message.success(this.menuForm.menuId ? '更新成功' : '新增成功');
                                this.dialogVisible = false;
                                this.getMenuList();
                                this.getAllMenus();
                                if (this.currentMenu.menuId) {
                                    this.treeDialogVisible = true;
                                    this.refreshSubTree();
                                }
                            } else {
                                this.$message.error((this.menuForm.menuId ? '更新' : '新增') + '失败：' + res.data.msg);
                            }
                        }).catch(error => {
                            this.$message.error((this.menuForm.menuId ? '更新' : '新增') + '异常：' + error.message);
                        });
                    }
                });
            }
        }
    });
</script>
</body>
</html>